﻿using System;
using System.Reflection;
using System.Runtime.InteropServices;
using EnvDTE;
using EnvDTE80;
using Extensibility;
using Microsoft.VisualStudio.CommandBars;
using System.Resources;
using System.Globalization;
using Microsoft.SqlServer.Management.UI.VSIntegration;

using System.Windows.Forms;

using System.Net;
using System.Xml;
using System.Diagnostics;
using System.IO;

namespace XEvents.Addin
{
    /// <summary>The object for implementing an Add-in.</summary>
    /// <seealso class='IDTExtensibility2' />
    [Guid("DFC2E856-2FC0-487F-BA7F-54378D6ADDDE"), ComVisible(true), ProgId("XEvents.Addin")]
    public class Connect : IDTExtensibility2, IDTCommandTarget
    {
        private DTE2 applicationObject;
        private AddIn addInInstance;
        private CommandBar menuBarCommandBar;
        private CommandBarControl viewMenu;
        private string viewMenuName;
        //private ObjectExplorerExtension oee;


        /// <summary>Implements the constructor for the Add-in object. Place your initialization code within this method.</summary>
        public Connect()
        {
        }

        /// <summary>Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary>
        /// <param term='application'>Root object of the host application.</param>
        /// <param term='connectMode'>Describes how the Add-in is being loaded.</param>
        /// <param term='addInInst'>Object representing this Add-in.</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
        {
            //oee = new ObjectExplorerExtension();

            addInInstance = (AddIn)addInInst;
            applicationObject = (DTE2)addInInstance.DTE;

            // list all of the commands
            foreach (Command cmd in applicationObject.Commands)
                System.Diagnostics.Debug.WriteLine(String.Format("{0}, {1}, {2}", cmd.Name, cmd.Guid, cmd.ID));

            //For SSMS this need to be set to ext_ConnectMode.ext_cm_Startup rather than ext_ConnectMode.ext_cm_UISetup
            if (connectMode == ext_ConnectMode.ext_cm_Startup)
            {
                object[] contextGUIDS = new object[] { };
                Commands2 commands = (Commands2)ServiceCache.ExtensibilityModel.Commands;

                try
                {
                    string resourceName;
                    ResourceManager resourceManager = new ResourceManager("XEvents.Addin.CommandBar", Assembly.GetExecutingAssembly());
                    CultureInfo cultureInfo = new CultureInfo(applicationObject.LocaleID);

                    if (cultureInfo.TwoLetterISOLanguageName == "zh")
                    {
                        System.Globalization.CultureInfo parentCultureInfo = cultureInfo.Parent;
                        resourceName = String.Concat(parentCultureInfo.Name, "View");
                    }
                    else
                    {
                        resourceName = String.Concat(cultureInfo.TwoLetterISOLanguageName, "View");
                    }

                    viewMenuName = resourceManager.GetString(resourceName);
                }
                catch
                {
                    viewMenuName = "View";
                }

                menuBarCommandBar = ((CommandBars)ServiceCache.ExtensibilityModel.CommandBars)["MenuBar"];
                viewMenu = menuBarCommandBar.Controls[viewMenuName];
                CommandBarPopup toolsPopup = (CommandBarPopup)viewMenu;

                Command command;
                try
                {
                    //Add a command to the Commands collection:
                    command = commands.AddNamedCommand2(addInInstance, "ShowSessionExplorer", "Show Extended Event Session Explorer", "Displays the Extended Event Session Explorer", true, 0, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStyleText, vsCommandControlType.vsCommandControlTypeButton);

                    if ((command != null) && (toolsPopup != null))
                    {
                        command.AddControl(toolsPopup.CommandBar, 1);
                    }
                }
                catch (System.ArgumentException)
                {
                }

                foreach (Command cmd in applicationObject.Commands)
                     System.Diagnostics.Debug.WriteLine(String.Format("{0}, {1}, {2}", cmd.Name, cmd.Guid, cmd.ID));

            }
        }

        /// <summary>Implements the OnDisconnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being unloaded.</summary>
        /// <param term='disconnectMode'>Describes how the Add-in is being unloaded.</param>
        /// <param term='custom'>Array of parameters that are host application specific.</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
        {
            foreach (Window w in ServiceCache.ExtensibilityModel.Windows)
            {
                if (w.Caption == "Extended Events Information")
                {
                    Properties.Settings.Default.AddinVisible = w.Visible;
                    Properties.Settings.Default.Save();
                }
            }
            Commands2 commands = (Commands2)ServiceCache.ExtensibilityModel.Commands;
            foreach (Command c in commands)
            {
                if (c.Name == "XEvents.Addin.ShowSessionExplorer" || c.Name == "XEvents.Addin.Display")
                    c.Delete();
            }
        }

        /// <summary>Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. Receives notification when the collection of Add-ins has changed.</summary>
        /// <param term='custom'>Array of parameters that are host application specific.</param>
        /// <seealso class='IDTExtensibility2' />		
        public void OnAddInsUpdate(ref Array custom)
        {
        }

        /// <summary>Implements the OnStartupComplete method of the IDTExtensibility2 interface. Receives notification that the host application has completed loading.</summary>
        /// <param term='custom'>Array of parameters that are host application specific.</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnStartupComplete(ref Array custom)
        {
            //Check Version
            if (Properties.Settings.Default.CheckVersion)
            {
                try { CheckVersionInfo(); }
                catch { }
            }
            if (Properties.Settings.Default.AddinVisible)
                CreateSessionExplorerWindow();
        }

        /// <summary>Implements the OnBeginShutdown method of the IDTExtensibility2 interface. Receives notification that the host application is being unloaded.</summary>
        /// <param term='custom'>Array of parameters that are host application specific.</param>
        /// <seealso class='IDTExtensibility2' />
        public void OnBeginShutdown(ref Array custom)
        {

        }

        /// <summary>Implements the QueryStatus method of the IDTCommandTarget interface. This is called when the command's availability is updated</summary>
        /// <param term='commandName'>The name of the command to determine state for.</param>
        /// <param term='neededText'>Text that is needed for the command.</param>
        /// <param term='status'>The state of the command in the user interface.</param>
        /// <param term='commandText'>Text requested by the neededText parameter.</param>
        /// <seealso class='Exec' />
        public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
        {
            if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
            {
                if (commandName == "XEvents.Addin.ShowSessionExplorer")
                {
                    status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;
                    return;
                }
            }
        }

        /// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
        /// <param term='commandName'>The name of the command to execute.</param>
        /// <param term='executeOption'>Describes how the command should be run.</param>
        /// <param term='varIn'>Parameters passed from the caller to the command handler.</param>
        /// <param term='varOut'>Parameters passed from the command handler to the caller.</param>
        /// <param term='handled'>Informs the caller if the command was handled or not.</param>
        /// <seealso class='Exec' />
        public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
        {
            handled = false;
            if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
            {
                if (commandName == "XEvents.Addin.ShowSessionExplorer")
                {
                    CreateSessionExplorerWindow();

                    handled = true;
                    return;
                }
            }
        }

        /// <summary>
        /// Creates the allocation window.
        /// </summary>
        /// <param name="application">The application.</param>
        /// <param name="addinInstance">The addin instance.</param>
        public void CreateSessionExplorerWindow()
        {
            Window toolWindow = SSMSAddinHelper.CreateToolWindow("XEvents.Addin.XEventSessionExplorer", 
                                new Guid("{E9B27AE4-24C3-4F24-B010-85FCA0090024}"), 
                                "Extended Events Information");

            toolWindow.Visible = true;
        }

        private static void CheckVersionInfo()
        {
            WebClient wc = new WebClient();
            XmlDocument xDoc = new XmlDocument();
            string s = wc.DownloadString(@"http://www.sqlclr.net/XEventsLatestBuild.xml");
            xDoc.LoadXml(s);
            string[] buildarray = xDoc.DocumentElement.Attributes["addin"].Value.Split('.');

            int major = Int32.Parse(buildarray[0]),
                minor = Int32.Parse(buildarray[1]),
                build = Int32.Parse(buildarray[2]),
                revision = Int32.Parse(buildarray[3]);

            if (Assembly.GetExecutingAssembly().GetName().Version.Major < major ||
                Assembly.GetExecutingAssembly().GetName().Version.Minor < minor ||
                Assembly.GetExecutingAssembly().GetName().Version.Build < build ||
                Assembly.GetExecutingAssembly().GetName().Version.Revision < revision)
            {
                NewVersionAvailable nva = new NewVersionAvailable(xDoc);
                nva.ShowDialog();
            }
        }

    }
}

